package cn.highedu.coolshark.product.service.impl;

import cn.highedu.coolshark.common.*;
import cn.highedu.coolshark.product.mapper.BrandCategoryMapper;
import cn.highedu.coolshark.product.mapper.BrandMapper;
import cn.highedu.coolshark.product.mapper.SpuMapper;
import cn.highedu.coolshark.product.pojo.dto.BrandAddNewDTO;
import cn.highedu.coolshark.product.pojo.dto.BrandQueryParamDTO;
import cn.highedu.coolshark.product.pojo.dto.BrandUpdateDTO;
import cn.highedu.coolshark.product.pojo.entity.Brand;
import cn.highedu.coolshark.product.pojo.vo.BrandListItemVO;
import cn.highedu.coolshark.product.pojo.vo.BrandStandardVO;
import cn.highedu.coolshark.product.service.IBrandService;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.TestOnly;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 处理品牌业务的实现类
 */
@Service
@Slf4j
public class BrandServiceImpl implements IBrandService {
    @Autowired
    private BrandMapper brandMapper;
    /**
     * 注入SpuMapper
     */
    @Autowired
    private SpuMapper spuMapper;
    /**
     * 注入BrandCategoryMapper
     */
    @Autowired
    private BrandCategoryMapper brandCategoryMapper;

    /**
     * 查询品牌列表
     * @return 品牌列表, 如果没有响应的品牌, 返回一个集合长度为0的列表
     */
    @Override
    @Transactional(readOnly = true) // 设置只读 该方法中不能有任何的修改动作
    public List<BrandListItemVO> list() {
        log.debug("开始处理【查询品牌列表】的业务, 无参数");
        List<BrandListItemVO> list = brandMapper.list();
        return list;
    }

    /**
     * 分页查询品牌列表
     * @param brandQueryParamDTO 封装分页查询相关数据
     * @return 分页数据
     */
    @Override
    @Transactional(readOnly = true)
    public PagedVO<BrandListItemVO> list(BrandQueryParamDTO brandQueryParamDTO) {
        log.debug("开始处理【分页查询品牌列表】的业务, 参数: {}", brandQueryParamDTO);
        // 查询具体的品牌数据列表
        List<BrandListItemVO> list = brandMapper.listByParam(brandQueryParamDTO);
        // 获取符合规则的总记录数
        int total = brandMapper.countByParam(brandQueryParamDTO);
        // 获取当前页码
        int pageNum = brandQueryParamDTO.getPageNum();
        // 获取每页的条数
        int pageSize = brandQueryParamDTO.getPageSize();
        // 创建分页对象
        PagedVO<BrandListItemVO> pagedVO = new PagedVO<>(pageNum, pageSize, total, list);
        // 返回结果
        return pagedVO;
    }

    /**
     * 启用品牌
     * @param id 品牌ID
     */
    @Override
    @Transactional
    public void setEnable(Long id) {
        updateEnableById(id, 1);
    }

    /**
     * 禁用品牌
     * @param id 品牌ID
     */
    @Override
    @Transactional
    public void setDisable(Long id) {
        updateEnableById(id, 0);
    }

    /**
     * 根据品牌id, 删除品牌数据
     * @param id 尝试删除的品牌的id
     */
    @Override
    @Transactional // 添加事务
    public void delete(Long id) {
        log.debug("开始处理【根据ID删除品牌】的业务, 参数: {}", id);
        // 当前品牌是否关联了类别
        {
            int count = brandCategoryMapper.countByBrand(id);
            if (count > 0) {
                String message = "删除品牌失败, 当前品牌仍关联类别";
                log.warn(message);
                throw new EntityIsAssociatedException(message);
            }
        }
        // 当前品牌是否关联了SPU
        {
            int count = spuMapper.countByBrand(id);
            if (count > 0) {
                String message = "删除品牌失败, 当前品牌仍关联商品";
                log.warn(message);
                throw new EntityIsAssociatedException(message);
            }
        }
        // 执行删除
        log.debug("即将执行删除数据, 参数: {}", id);
        int rows = brandMapper.deleteById(id);
        if (rows != 1) {
            String message = "删除品牌失败, 服务器忙, 请稍后再试";
            log.warn(message);
            throw new EntityDeleteFailedException(message);
        }
    }

    /**
     * 添加品牌
     * @param brandAddNewDTO 品牌数据
     */
    @Override
    @Transactional
    public void addNew(BrandAddNewDTO brandAddNewDTO) {
        log.debug("开始处理【添加品牌】的业务, 参数: {}", brandAddNewDTO);
        // 确保品牌名是唯一的
        String name = brandAddNewDTO.getName();
        int count = brandMapper.countByName(name);
        if (count > 0) {
            String message = "添加品牌失败, 品牌名称【" + name + "】已经被使用";
            log.warn(message);
            throw new EntityAlreadyExistsException(message);
        }
        // 创建品牌对象, 用于保存数据
        Brand brand = new Brand();
        BeanUtils.copyProperties(brandAddNewDTO, brand);
        // 插入数据
        log.debug("即将向数据库中插入数据: {}", brand);
        int rows = brandMapper.insert(brand);
        if (rows != 1) {
            String message = "添加品牌失败, 服务器忙, 请稍后再试";
            log.debug(message);
            throw new EntitySaveFailedException(message);
        }
    }

    /**
     * 根据品牌ID, 修改品牌详情
     *
     * @param id             品牌ID
     * @param brandUpdateDTO 新的品牌信息
     */
    @Override
    @Transactional
    public void updateInfoById(Long id, BrandUpdateDTO brandUpdateDTO) {
        log.debug("开始处理【修改品牌详情】的业务, 参数ID: {}, 新数据: {}", id, brandUpdateDTO);
        // 修改数据之前检查名称是否被使用
        int count = brandMapper.countByNameAndNotId(id, brandUpdateDTO.getName());
        if (count > 0) {
            String message = "修改品牌详情失败, 品牌名已被使用";
            log.warn(message);
            throw new EntityAlreadyExistsException(message);
        }
        Brand brand = new Brand();
        BeanUtils.copyProperties(brandUpdateDTO, brand);
        brand.setId(id);

        // 修改数据
        log.debug("即将修改数据: {}", brand);
        int rows = brandMapper.update(brand);
        if (rows != 1) {
            String message = "修改品牌详情失败, 服务器忙, 请稍后再试";
            log.warn(message);
            throw new EntityUpdateFailedException(message);
        }
    }

    /**
     * 根据ID获取品牌详情
     * @param id 品牌ID
     * @return 匹配的品牌数据详情, 如果没有匹配的数据, 返回null
     */
    @Override
    @Transactional(readOnly = true)
    public BrandStandardVO getStandardById(Long id) {
        log.debug("开始处理【根据ID查询品牌详情】的业务, 参数: {}", id);
        BrandStandardVO queryResult = brandMapper.getStandardById(id);
        if (queryResult == null) {
            String message = "根据id查询品牌详情失败, 尝试访问的数据不存在";
            log.debug(message);
            throw new EntityNotFoundException(message);
        }
        log.debug("即将返回品牌详情: {}", queryResult);
        return queryResult;
    }

    /**
     * 根据类别id查询相应的品牌列表
     * @param categoryId 列别id
     * @return 品牌列表
     */
    @Override
    public List<BrandListItemVO> listByCategory(Long categoryId) {
        log.debug("开始处理【根据类别id查询相应的品牌列表】的业务, 参数: {}", categoryId);
        List<BrandListItemVO> list = brandMapper.listByCategory(categoryId);
        if (list == null || list.isEmpty()) {
            String message = "该类别没有相匹配的品牌";
            log.debug(message);
            throw new EntityNotFoundException(message);
        }
        return list;
    }

    /**
     * 启用或禁用品牌
     */
    private void updateEnableById(Long id, Integer enable) {
        log.debug("开始处理【品牌】的业务, ID: {}, 目标状态: {}", id, enable);
        // 准备执行更新
        Brand brand = new Brand();
        brand.setId(id);
        brand.setEnable(enable);
        log.debug("即将执行修改数据, 参数: {}", brand);
        int rows = brandMapper.update(brand);
        if (rows != 1) {
            String message = "启用/禁用 品牌失败, 服务器忙, 请您稍后再试";
            log.warn(message);
            throw new EntityUpdateFailedException(message);
        }
    }
}
